#include "Carrito.h"
#include "../fisica/CarritoFisica.h"
#include <iostream>
using namespace std;

Carrito::Carrito(double x, double y, double ancho, double alto, string pathImagen): Elemento(x, y, ancho, alto, pathImagen) {
//	cout << "RuedaDer X: " << x-ancho/4 << " Y: " << y- alto/2 << endl;
//	cout << " X: " << x<< " Y: " << y << endl;

	this->ruedaDerecha = new Rueda(this->getX()+this->getAncho()*3/4,this->getY() + this->getAlto()*9/8, alto/4, alto/4, "img/rueda.png");
	this->ruedaIzquierda = new Rueda(this->getX()+this->getAncho()*1/4,this->getY() + this->getAlto()*9/8 ,alto/4, alto/4, "img/rueda.png");

	this->frameActual = 1;
	this->cantFrames = 8;

	this->posSogaIzqX = 0;
	this->posSogaIzqY = 0;
	this->sogaDerUnida = NULL;
	this->sogaIzqUnida = NULL;
	this->posSogaDerX = ancho;
	this->posSogaDerY = 0;
	this->sogaIzqInicial = false;
	this->sogaDerInicial = false;

}

Carrito::~Carrito() {
	// TODO Auto-generated destructor stub
}

void Carrito::rotar(double angulo) {
	this->setAnguloRotacion(angulo);
	this->actualizarReferencias();
}


bool Carrito::aceptaSoga(){
	if (this->sogaIzqUnida && this->sogaDerUnida)
		return false;
	return true;
}

void Carrito::dibujar(double x, double y, double ancho, double alto,SDL_Renderer* renderer){
	Elemento::dibujar(x,y,ancho,alto,renderer);
}

bool Carrito::esAnimable(){
	//ESTO LO VEMOS DESPUES
	//if ( this->getEntidadFisica()->obtenerCuerpo()->GetLinearVelocity().x > 0 ){
	//	return true;
//	} else {
		return false;
	//}
}

void Carrito::actualizarValoresFisicos() {

	this->xAnterior = this->x;
	Elemento::actualizarValoresFisicos();

//	if (this->getEntidadFisica()->isPelotaAdentro()){
//		cout << "Tuvo la pelota adentro"<< endl;
//		this->setPelotaAdentro(true);
//	}
}


void Carrito::activarSogaPosInicial() {
	this->sogaIzqInicial = true;
}
void Carrito::activarSogaPosFinal() {
	this->sogaDerInicial = true;
}

void Carrito::mover(double centroX, double centroY) {
	Elemento::mover(centroX, centroY);
	this->actualizarReferencias();
}

void Carrito::actualizarReferencias() {

	if (this->sogaIzqUnida != NULL) {

	//	cout << "Actualizo soga Izq" << endl;

		pair<double,double> parXYAObtener = this->obtenerPosicionSoga(0);

		if (this->sogaIzqInicial) {

//			cout << "SOGA IZQ INICIAL" << endl;
			this->sogaIzqUnida->setPosicionInicial(
					parXYAObtener.first,
					parXYAObtener.second);
		} else {
//			cout << "NOO SOGA IZQ INICIAL" << endl;
			this->sogaIzqUnida->setPosicionFinal(
					parXYAObtener.first,
					parXYAObtener.second);
		}
	}
	if (this->sogaDerUnida != NULL) {

	//	cout << "Actualizo soga Der" << endl;

		pair<double,double> parXYAObtener = this->obtenerPosicionSoga(1);

		if (this->sogaDerInicial) {
//			cout << "SOGA DER INICIAL" << endl;

			this->sogaDerUnida->setPosicionInicial(
					parXYAObtener.first,
					parXYAObtener.second);
		} else {
//			cout << "SOGA NOOO DER INICIAL" << endl;

			this->sogaDerUnida->setPosicionFinal(
					parXYAObtener.first,
					parXYAObtener.second);
		}
	}
}

void Carrito::agregarSogaInicial(Elemento* soga) {


	if (this->sogaIzqUnida) {
		cout << "Habia simulado anteriormente izq " << endl;
		if (this->sogaIzqUnida->getIdElemento() == soga->getIdElemento()) {
			pair<double,double> parXYAObtener = this->obtenerPosicionSoga(0);
			soga->setPosicionInicial(parXYAObtener.first,parXYAObtener.second);
			return;
		}
	}

	if (this->sogaDerUnida) {
		cout << "Habia simulado anteriormente der" << endl;
		if (this->sogaDerUnida->getIdElemento() == soga->getIdElemento()) {
			pair<double,double> parXYAObtener = this->obtenerPosicionSoga(1);
			soga->setPosicionInicial(parXYAObtener.first,parXYAObtener.second);
			return;
		}
	}

	// No habia simulado previamente
	pair<double, double> posicionInicioSoga = soga->getPosicionInicial();
	double medioCarrito = this->getX() + this->getAncho() / 2;
	cout << "medio carrito: " << medioCarrito << "y posicion inicio soga x:  "
			<< posicionInicioSoga.first << endl;

	if (posicionInicioSoga.first <= medioCarrito) {
		pair<double,double> parXYAObtener = this->obtenerPosicionSoga(0);
		soga->setPosicionInicial(parXYAObtener.first,parXYAObtener.second);
		this->sogaIzqUnida = soga;
		this->sogaIzqInicial = true;
	} else {
		pair<double,double> parXYAObtener = this->obtenerPosicionSoga(1);
		soga->setPosicionInicial(parXYAObtener.first,parXYAObtener.second);
		this->sogaDerUnida = soga;
		this->sogaDerInicial = true;
	}

}

void Carrito::agregarSogaFinal(Elemento* soga) {

	if (this->sogaIzqUnida) {
		if (this->sogaIzqUnida->getIdElemento() == soga->getIdElemento()) {
			pair<double,double> parXYAObtener = this->obtenerPosicionSoga(0);
			soga->setPosicionFinal(parXYAObtener.first,parXYAObtener.second);
			this->sogaIzqUnida = soga;
			this->sogaIzqInicial = false;
			return;
		}
	}

	if (this->sogaDerUnida) {
		if (this->sogaDerUnida->getIdElemento() == soga->getIdElemento()) {
			pair<double,double> parXYAObtener = this->obtenerPosicionSoga(1);
			soga->setPosicionFinal(parXYAObtener.first,parXYAObtener.second);
			this->sogaDerUnida = soga;
			this->sogaDerInicial = false;
			return;
		}
	}

	cout << "agregar soga final balancin " << endl;
	pair<double, double> posicionFinSoga = soga->getPosicionFinal();
	double medioCarrito = this->getX() + this->getAncho() / 2;
	cout << "medio carrito: " << medioCarrito << "y posicion inicio soga x:  "
			<< posicionFinSoga.first << endl;

	if (posicionFinSoga.first <= medioCarrito) {
		pair<double,double> parXYAObtener = this->obtenerPosicionSoga(0);
		soga->setPosicionFinal(parXYAObtener.first,parXYAObtener.second);
		this->sogaIzqUnida = soga;
		this->sogaIzqInicial = false;
	} else {
		pair<double,double> parXYAObtener = this->obtenerPosicionSoga(1);
		soga->setPosicionFinal(parXYAObtener.first,parXYAObtener.second);
		this->sogaDerUnida = soga;
		this->sogaDerInicial = false;
	}

}

void Carrito::eliminarSoga(Elemento* soga) {
	cout << "soga a eliminar en " << this->getTipo()  << " con id: " << soga->getIdElemento() << endl;
	if (this->sogaIzqUnida) {
		cout << "soga izq con id: " << this->sogaIzqUnida->getIdElemento()
				<< endl;

		if (this->sogaIzqUnida->getIdElemento() == soga->getIdElemento()){
			cout << "Elimino soga izquierda" << endl;
			this->sogaIzqUnida = NULL;
			this->sogaIzqInicial = false;
			cout << "Elimine soga izquierda unida" << endl;
			return;
		}
	}

	if (this->sogaDerUnida) {
		cout << "soga der con id: " << this->sogaDerUnida->getIdElemento()
				<< endl;

		if (this->sogaDerUnida->getIdElemento() == soga->getIdElemento()){
			cout << "Elimino soga derecha" << endl;
			this->sogaDerUnida = NULL;
			this->sogaDerInicial = false;
			return;
		}
	}
}

int Carrito::seSuperpone(Elemento* elemento) {
	if (elemento->getTipo() == "soga")
		return 0;
	return 2;
}

void Carrito::eliminarReferencias(list<Elemento*>* elementosCanvas) {

	pair<Elemento*, Elemento*> extremosSoga;
	pair<Elemento*, Elemento*> extremosSogaIzq, extremosSogaDer;

	if (this->sogaIzqUnida) {

		this->sogaIzqUnida->eliminarReferencias(elementosCanvas);
		delete this->sogaIzqUnida;
	}
	if (this->sogaDerUnida) {
		this->sogaDerUnida->eliminarReferencias(elementosCanvas);
		delete this->sogaDerUnida;
	}
}

int Carrito::haySogaIzqUnida() {
	if (this->sogaIzqUnida)
		return 1;
	return 0;
}

int Carrito::haySogaDerUnida() {
	if (this->sogaDerUnida)
		return 1;
	return 0;
}

bool Carrito::esBasico() {
	return false;
}

bool Carrito::sogaEnPosInicial() {
	return this->sogaIzqInicial;
}

bool Carrito::sogaEnPosFinal() {
	return this->sogaDerInicial;

}

pair<Elemento*, Elemento*> Carrito::obtenerExtremos() {
	pair<Elemento*, Elemento*> extremos;
	extremos.first = NULL;
	extremos.second = NULL;
	cout << "estoy en carrito con haySogaIzq: " << this->haySogaIzqUnida()
			<< " y hay soga derecha: " << this->haySogaDerUnida() << endl;

	if (this->sogaIzqUnida) {
		cout << "TIENE SOGA IZQ " << endl;
		extremos.first = this->sogaIzqUnida;
	}
	if (this->sogaDerUnida) {
		cout << "TIENE SOGA DER " << endl;
		extremos.second = this->sogaDerUnida;
	}
	return extremos;
}

void Carrito::setSogaInicial(Elemento* elem) {
	this->sogaIzqUnida = elem;
}

void Carrito::setSogaFinal(Elemento* elem) {
	this->sogaDerUnida = elem;

}

void Carrito::jointearElemento(b2World* world){
	cout<<"AGREGO RUEDAS AL CARRITO"<<endl;
	CarritoFisica* carrito = (CarritoFisica*)this->getEntidadFisica();
	this->ruedaDerecha->setElementoFisico(carrito->getRuedaDerecha());
	this->ruedaIzquierda->setElementoFisico(carrito->getRuedaIzquierda());
}

pair<double,double> Carrito::obtenerPosicionSoga(int sentido){

	pair<double,double> posicionXYAObtener;

	// Soga izquierda
	if (sentido == 0){

		double angulo = this->getAnguloRotacion() - 360;

		double xTrasladado = -this->getAncho()/2 + this->getAncho() * PROPORCION_SOGA_CARRITO_X_IZQ;
		double yTrasladado = this->getAlto()/2 - this->getAlto() * PROPORCION_SOGA_CARRITO_Y;

		double xRotado = xTrasladado * cos(angulo * PI / 180.0) +
				yTrasladado	* sin(angulo * PI/ 180.0);
		double yRotado = -xTrasladado * sin(angulo * PI / 180.0)	+
				yTrasladado	* cos(angulo * PI/ 180.0);

		double xAObtener = this->getX() + this->getAncho()/2 + xRotado;
		double yAObtener = this->getY() + this->getAlto()/2  - yRotado;

		posicionXYAObtener.first = xAObtener;
		posicionXYAObtener.second = yAObtener;
	}
	// Soga derecha
	else if (sentido == 1){
		double angulo = 360 - this->getAnguloRotacion();

		double xTrasladado = -this->getAncho()/2 + this->getAncho() * PROPORCION_SOGA_CARRITO_X_DER;
		double yTrasladado = this->getAlto()/2 - this->getAlto() * PROPORCION_SOGA_CARRITO_Y;

		double xRotado = xTrasladado * cos(angulo * PI / 180.0) -
				yTrasladado	* sin(angulo * PI/ 180.0);
		double yRotado = xTrasladado * sin(angulo * PI / 180.0)	+
				yTrasladado	* cos(angulo * PI/ 180.0);

		double xAObtener = this->getX() + this->getAncho()/2 + xRotado;
		double yAObtener = this->getY() + this->getAlto()/2  - yRotado;

		posicionXYAObtener.first = xAObtener;
		posicionXYAObtener.second = yAObtener;
	}

	return posicionXYAObtener;
}

